FastAPI তে Authentication এবং Authorization ব্যবস্থাপনা একটি গুরুত্বপূর্ণ অংশ, কারণ এটি অ্যাপ্লিকেশন এবং API-এর সুরক্ষা নিশ্চিত করে। FastAPI তে Authentication এবং Authorization দুটি গুরুত্বপূর্ণ কাজ:
- Authentication: এটি নিশ্চিত করে যে ব্যবহারকারী বা ক্লায়েন্ট প্রকৃতপক্ষে সঠিক পরিচয়ে লগইন করেছেন কিনা।
- Authorization: এটি নিশ্চিত করে যে একটি ব্যবহারকারী বা ক্লায়েন্ট নির্দিষ্ট সম্পদ বা কার্যকলাপে অ্যাক্সেস করার অনুমতি পেয়েছে কিনা।
FastAPI তে এই দুটি কাজ সহজে সম্পাদন করা যায়, এবং এখানে আমরা সেগুলোর জন্য সাধারণ পদ্ধতি সম্পর্কে আলোচনা করব।
Authentication: Basic Authentication এবং OAuth2
1. Basic Authentication
Basic Authentication হল একটি সরল পদ্ধতি যেখানে ব্যবহারকারীর username এবং password যাচাই করা হয়। FastAPI-তে এটি Depends ডেকোরেটর ব্যবহার করে বাস্তবায়িত করা হয়।
উদাহরণ: Basic Authentication
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
# Basic Authentication
def authenticate_user(credentials: HTTPBasicCredentials = Depends(security)):
correct_username = "admin"
correct_password = "password123"
if credentials.username != correct_username or credentials.password != correct_password:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"},
)
return credentials.username
@app.get("/protected/")
def read_protected(user: str = Depends(authenticate_user)):
return {"message": f"Hello, {user}! You have access to this route."}
এখানে:
HTTPBasic(): Basic Authentication ব্যবহারের জন্য FastAPI এর built-in ফাংশন।authenticate_user: একটি ফাংশন যাusernameএবংpasswordযাচাই করে। যদি সঠিক না হয়, তাহলে একটি 401 Unauthorized ত্রুটি দেখাবে।Depends(security): Authentication ফাংশনটিDependsডেকোরেটর ব্যবহার করে নির্ধারণ করা হয়েছে।
রিকোয়েস্ট উদাহরণ:
আপনি /protected/ এ রিকোয়েস্ট পাঠানোর সময় Basic Authentication হেডার দিতে হবে:
Authorization: Basic YWRtaW46cGFzc3dvcmQxMjM=
2. OAuth2 Authentication
FastAPI-তে OAuth2 ব্যবহার করে তৃতীয় পক্ষের সিস্টেমের মাধ্যমে authentication করা হয়, যেমন Google বা Facebook লগইন। এটি সাধারণত JWT (JSON Web Token) এর সাথে ব্যবহার করা হয়।
উদাহরণ: OAuth2 with Password Flow
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Fake user database for demonstration
fake_users_db = {
"johndoe": {
"username": "johndoe",
"password": "secretpassword",
}
}
# Token validation (simplified)
def verify_token(token: str):
if token == "fake-jwt-token":
return {"username": "johndoe"}
raise HTTPException(status_code=401, detail="Invalid token")
@app.post("/token")
def generate_token(username: str, password: str):
if fake_users_db.get(username) and fake_users_db[username]["password"] == password:
return {"access_token": "fake-jwt-token", "token_type": "bearer"}
raise HTTPException(status_code=401, detail="Invalid credentials")
@app.get("/protected/")
def protected_route(token: str = Depends(oauth2_scheme)):
user = verify_token(token)
return {"message": f"Hello, {user['username']}! You have access to this route."}
এখানে:
OAuth2PasswordBearer: এটি একটি FastAPI ক্লাস যা OAuth2 Authentication এর জন্য ব্যবহৃত হয়। এর মাধ্যমে tokenUrl দেওয়া হয় যেখানে ব্যবহারকারী তাদের টোকেন পেতে পারে।verify_token: এটি একটি ফাংশন যা টোকেন যাচাই করে। সাধারণত এটি একটি JWT যাচাইয়ের জন্য ব্যবহৃত হয়, কিন্তু এখানে একটি ফেক টোকেন ব্যবহার করা হয়েছে উদাহরণ হিসেবে।generate_token: এটি একটি POST রিকোয়েস্ট যা ইউজারনেম এবং পাসওয়ার্ড দিয়ে JWT টোকেন জেনারেট করে।
রিকোয়েস্ট উদাহরণ:
POST
/tokenendpoint এর মাধ্যমে আপনি টোকেন পেতে পারেন:{ "username": "johndoe", "password": "secretpassword" }রেসপন্স:
{ "access_token": "fake-jwt-token", "token_type": "bearer" }তারপর, সেই টোকেনটি ব্যবহার করে
/protected/এ রিকোয়েস্ট করতে হবে:Authorization: Bearer fake-jwt-token
Authorization: Role-Based Access Control (RBAC)
Authorization হল এটি নিশ্চিত করা যে ব্যবহারকারী কি করতে পারবে। FastAPI তে এটি সাধারণত JWT বা OAuth2 ব্যবহারের মাধ্যমে কন্ট্রোল করা হয়, যেখানে ব্যবহারকারীর roles চেক করা হয়।
উদাহরণ: Role-Based Access Control (RBAC)
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Fake user database for demonstration
fake_users_db = {
"admin": {
"username": "admin",
"password": "adminpassword",
"role": "admin",
},
"johndoe": {
"username": "johndoe",
"password": "userpassword",
"role": "user",
}
}
# Token validation and Role Authorization
def verify_token(token: str):
if token == "fake-jwt-token-admin":
return {"username": "admin", "role": "admin"}
elif token == "fake-jwt-token-user":
return {"username": "johndoe", "role": "user"}
raise HTTPException(status_code=401, detail="Invalid token")
def get_current_user(token: str = Depends(oauth2_scheme)):
return verify_token(token)
def check_admin(user: dict = Depends(get_current_user)):
if user["role"] != "admin":
raise HTTPException(status_code=403, detail="You do not have access to this resource")
return user
@app.get("/admin/")
def admin_area(user: dict = Depends(check_admin)):
return {"message": f"Hello, {user['username']}! You have admin access."}
এখানে:
verify_token: JWT টোকেন যাচাই করার মাধ্যমে ব্যবহারকারী এবং তার রোল (role) নিশ্চিত করা হয়।check_admin: যদি ব্যবহারকারীর রোলadminনা হয়, তবে 403 Forbidden ত্রুটি দেখানো হয়।/admin/রাউটটি শুধুমাত্র admin রোলের ব্যবহারকারীদের জন্য অ্যাক্সেসযোগ্য।
রিকোয়েস্ট উদাহরণ:
- POST
/tokenendpoint থেকে আপনিfake-jwt-token-adminপেতে পারেন। - তারপর
/admin/এ রিকোয়েস্ট করতেBearer fake-jwt-token-adminব্যবহার করতে হবে।
FastAPI তে Authentication এবং Authorization একসাথে ব্যবহারের মাধ্যমে আপনি নিরাপদ ও স্কেলেবল API তৈরি করতে পারেন। Basic Authentication, OAuth2 এবং JWT এর মাধ্যমে সঠিকভাবে Authentication নিশ্চিত করা যায়, এবং Role-Based Access Control (RBAC) এর মাধ্যমে Authorization কন্ট্রোল করা যায়। FastAPI-এর এই সুবিধাগুলো ব্যবহার করে আপনি সুরক্ষিত এবং শক্তিশালী ওয়েব অ্যাপ্লিকেশন তৈরি করতে পারবেন।
OAuth2 একটি জনপ্রিয় অথেনটিকেশন প্রোটোকল যা নিরাপদ এবং স্কেলেবল অ্যাপ্লিকেশন তৈরিতে সাহায্য করে। FastAPI তে OAuth2 ব্যবহার করে অ্যাপ্লিকেশনে অথেনটিকেশন এবং অথরাইজেশন কনফিগার করা খুবই সহজ। এখানে, আমরা দেখব কিভাবে OAuth2-এর মাধ্যমে অথেনটিকেশন কনফিগার করা যায় এবং ব্যবহারকারীকে নিরাপদভাবে অ্যাপ্লিকেশনে প্রবেশ করতে দেয়।
OAuth2 কী?
OAuth2 হল একটি authorization framework, যা ব্যবহারকারীদের তাদের credentials (যেমন ইউজারনেম এবং পাসওয়ার্ড) প্রদান না করেই থার্ড-পার্টি অ্যাপ্লিকেশনগুলিকে তাদের ডাটা অ্যাক্সেস করতে দেয়। এতে Access Tokens ব্যবহার করা হয়, যা ব্যবহারকারীর অথেনটিকেশন ও অথরাইজেশন যাচাই করে।
FastAPI তে OAuth2 ইমপ্লিমেন্টেশন সাধারণত Bearer Token অথবা Authorization Code Flow এর মাধ্যমে করা হয়।
Step 1: FastAPI তে OAuth2 Authentication কনফিগার করা
FastAPI তে OAuth2 কনফিগার করতে, প্রথমে আপনাকে OAuth2PasswordBearer এবং OAuth2PasswordRequestForm ক্লাস ব্যবহার করতে হবে। এগুলি FastAPI দ্বারা সরবরাহিত ক্লাস যা সহজেই OAuth2 ফ্লো ইমপ্লিমেন্ট করতে সহায়ক।
১. OAuth2 কনফিগারেশন এবং Access Token তৈরি
প্রথমে, আপনাকে OAuth2PasswordBearer এবং OAuth2PasswordRequestForm ব্যবহার করে একটি অথেনটিকেশন সিস্টেম তৈরি করতে হবে।
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from typing import Union
app = FastAPI()
# OAuth2PasswordBearer: token URL প্রদান করে
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Pydantic model: User and Token model
class User(BaseModel):
username: str
password: str
class Token(BaseModel):
access_token: str
token_type: str
# Dummy database for users
fake_users_db = {
"johndoe": {
"username": "johndoe",
"password": "secretpassword", # This should be hashed in real apps
}
}
# Fake function to simulate password checking
def fake_verify_password(plain_password: str, hashed_password: str) -> bool:
return plain_password == hashed_password
# Dummy function to simulate retrieving a user
def fake_get_user(username: str):
if username in fake_users_db:
user = fake_users_db[username]
return User(username=user["username"], password=user["password"])
return None
# Dependency to get the current user from token
def get_current_user(token: str = Depends(oauth2_scheme)):
# In a real app, you would decode the token and get user info here.
user = fake_get_user(token) # This is just for demo purposes
if user is None:
raise HTTPException(status_code=401, detail="Invalid credentials")
return user
এখানে:
OAuth2PasswordBearer: একটি স্কিমা যা Bearer token চেক করার জন্য ব্যবহৃত হয়।Token: Access token ধারণ করে যা OAuth2 এর মাধ্যমে ব্যবহৃত হয়।
Step 2: Token Generation (Token URL)
এখন আমরা একটি token endpoint তৈরি করব যেখানে ব্যবহারকারীরা তাদের ইউজারনেম এবং পাসওয়ার্ড ব্যবহার করে টোকেন পাবেন।
from fastapi import Form
@app.post("/token", response_model=Token)
async def login_for_access_token(username: str = Form(...), password: str = Form(...)):
user = fake_get_user(username)
if user is None or not fake_verify_password(password, user.password):
raise HTTPException(status_code=401, detail="Invalid credentials")
# Here, a real app would issue a JWT token
return {"access_token": username, "token_type": "bearer"}
এখানে, login_for_access_token ব্যবহারকারীকে তাদের username এবং password দিয়ে লগইন করার সুযোগ দেয় এবং সঠিক হলে একটি Bearer token প্রদান করে।
রিকোয়েস্ট উদাহরণ:
POST /token
username: johndoe
password: secretpassword
রেসপন্স:
{
"access_token": "johndoe",
"token_type": "bearer"
}
Step 3: Token দিয়ে Protected Route Access করা
এখন আমরা OAuth2 token সহ একটি নিরাপদ route তৈরি করব, যা শুধুমাত্র অনুমোদিত ব্যবহারকারীদের জন্য অ্যাক্সেসযোগ্য হবে।
@app.get("/users/me", response_model=User)
async def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
এখানে, get_current_user ডিপেনডেন্সি টোকেন যাচাই করে এবং বর্তমান ব্যবহারকারীকে ফেরত দেয়।
রিকোয়েস্ট উদাহরণ (Token সহ):
GET /users/me
Header:
Authorization: Bearer johndoe
রেসপন্স:
{
"username": "johndoe",
"password": "secretpassword"
}
Step 4: Token Expiry (Optional)
একটি প্রকৃত অ্যাপে, token expiry এবং refresh token সিস্টেমও থাকতে পারে। এখানে JWT (JSON Web Token) ব্যবহার করা যায়, যা টোকেনের expiry time সেট করতে দেয়। FastAPI এ JWT সহ OAuth2 ব্যবহার করা খুবই জনপ্রিয়।
এটি সাধারণত PyJWT লাইব্রেরির মাধ্যমে করা হয়:
pip install pyjwt
Step 5: JWT সহ OAuth2 Authentication
JWT ব্যবহার করে token তৈরি এবং যাচাই করার জন্য, আপনাকে JWT লাইব্রেরি এবং OAuth2PasswordBearer সেটআপ করতে হবে।
import jwt
from datetime import datetime, timedelta
from fastapi import HTTPException
SECRET_KEY = "mysecretkey" # In production, use a secret key securely stored
# JWT token generation function
def create_access_token(data: dict, expires_delta: timedelta = timedelta(hours=1)):
to_encode = data.copy()
expire = datetime.utcnow() + expires_delta
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm="HS256")
return encoded_jwt
# Token generation with JWT
@app.post("/token", response_model=Token)
async def login_for_access_token(username: str = Form(...), password: str = Form(...)):
user = fake_get_user(username)
if user is None or not fake_verify_password(password, user.password):
raise HTTPException(status_code=401, detail="Invalid credentials")
# Create JWT access token
access_token = create_access_token(data={"sub": username})
return {"access_token": access_token, "token_type": "bearer"}
এখানে, create_access_token ফাংশনটি JWT token তৈরি করে এবং exp (expiry) সেট করে। তারপর আমরা এই টোকেনটি ব্যবহারকারীর জন্য তৈরি করি এবং ফেরত দিই।
FastAPI তে OAuth2 ব্যবস্থাপনা খুবই সহজ এবং স্কেলেবল। আপনি OAuth2PasswordBearer এবং JWT (JSON Web Token) এর মাধ্যমে নিরাপদ অথেনটিকেশন এবং অথরাইজেশন সিস্টেম তৈরি করতে পারেন। OAuth2 এর মাধ্যমে Bearer token ব্যবহারের ফলে আপনার অ্যাপ্লিকেশন আরও নিরাপদ এবং ব্যবহারকারী-বান্ধব হয়।
FastAPI তে JWT (JSON Web Token) ব্যবহার করে User Authentication করা একটি সাধারণ এবং শক্তিশালী পদ্ধতি। JWT-কে সাধারণত API Authentication এবং Authorization এর জন্য ব্যবহার করা হয়, যেখানে ক্লায়েন্ট এবং সার্ভারের মধ্যে নিরাপদভাবে ডাটা শেয়ার করা হয়। JWT ব্যবহার করে আপনি ব্যবহারকারীর লগইন সেশন ম্যানেজ করতে পারেন এবং ব্যবহারকারীর অনুমোদন (Authorization) যাচাই করতে পারেন।
এখানে, আমরা দেখব কিভাবে FastAPI তে JWT ব্যবহার করে ব্যবহারকারীর Authentication এবং Authorization তৈরি করা যায়।
Step 1: প্রয়োজনীয় লাইব্রেরি ইনস্টল করা
JWT ব্যবহার করার জন্য আমাদের PyJWT এবং passlib লাইব্রেরি ইনস্টল করতে হবে। passlib ব্যবহার করে আমরা ব্যবহারকারীর পাসওয়ার্ড হ্যাশিং করতে পারি।
pip install pyjwt passlib[bcrypt] fastapi uvicorn
Step 2: JWT Token Generation এবং User Authentication
প্রথমে, JWT টোকেন তৈরির জন্য একটি পদ্ধতি তৈরি করতে হবে এবং তারপর সেটি ব্যবহারকারীর লগইন করার সময় ব্যবহার করব।
উদাহরণ: JWT Token Generation
import jwt
from datetime import datetime, timedelta
from passlib.context import CryptContext
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from typing import Optional
# পাসওয়ার্ড হ্যাশিং কনটেক্সট
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# JWT সিক্রেট কিওয়ার
SECRET_KEY = "mysecretkey"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
# FastAPI অ্যাপ শুরু করা
app = FastAPI()
# OAuth2PasswordBearer কনফিগারেশন
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# User Model
class User(BaseModel):
username: str
class UserInDB(User):
hashed_password: str
# Fake user data for demonstration
fake_users_db = {
"testuser": {
"username": "testuser",
"hashed_password": pwd_context.hash("testpassword")
}
}
# JWT টোকেন তৈরি করা
def create_access_token(data: dict, expires_delta: timedelta | None = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
# ব্যবহারকারী যাচাই করা
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def get_user(db, username: str):
if username in db:
user_dict = db[username]
return UserInDB(**user_dict)
return None
# Token তৈরি করার পদ্ধতি
@app.post("/token")
async def login_for_access_token(form_data: OAuth2PasswordBearer):
user = get_user(fake_users_db, form_data.username)
if not user or not verify_password(form_data.password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": form_data.username}, expires_delta=access_token_expires
)
return {"access_token": access_token, "token_type": "bearer"}
উদাহরণ বর্ণনা:
create_access_token(): এই ফাংশনটি JWT টোকেন তৈরি করে এবং এর মধ্যেsub(subject),exp(expire time) যুক্ত করে।verify_password(): পাসওয়ার্ডের হ্যাশ যাচাই করার জন্য ব্যবহৃত হয়।get_user(): ফেক ডাটাবেস থেকে ব্যবহারকারী অনুসন্ধান করে।
এটি একটি সাধারণ login endpoint তৈরি করেছে যা JWT টোকেন ফিরিয়ে দেয়।
Step 3: JWT Token ব্যবহার করে Protected Endpoint
এখন, আমরা একটি protected endpoint তৈরি করব, যেখানে JWT টোকেন প্রয়োজন হবে।
উদাহরণ: Protected Endpoint
from fastapi import Depends
# JWT Token যাচাই করা
def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
return username
except jwt.PyJWTError:
raise credentials_exception
# Protected Route
@app.get("/users/me")
async def read_users_me(current_user: str = Depends(get_current_user)):
return {"username": current_user}
উদাহরণ বর্ণনা:
get_current_user(): এই ফাংশনটি JWT টোকেন যাচাই করে এবং এটি বৈধ হলে ব্যবহারকারীর তথ্য ফেরত পাঠায়।/users/me: একটি protected route যা ব্যবহারকারীকে তাদের নিজের তথ্য ফেরত দেয় যদি তারা একটি বৈধ JWT টোকেন প্রদান করে।
রিকোয়েস্ট উদাহরণ (JWT টোকেন সহ):
curl -X 'GET' \
'http://127.0.0.1:8000/users/me' \
-H 'accept: application/json' \
-H 'Authorization: Bearer <JWT_TOKEN>'
Step 4: FastAPI-তে JWT Authorization Middleware (Optional)
FastAPI তে আপনি JWT যাচাই করার জন্য middleware ব্যবহার করতে পারেন, যা API-তে প্রতিটি রিকোয়েস্টের জন্য JWT টোকেন যাচাই করবে।
ফাস্টএপিআই তে JWT (JSON Web Token) ব্যবহার করে User Authentication একটি শক্তিশালী এবং সহজ উপায়। এটি API-তে নিরাপত্তা এবং অনুমোদন (Authorization) যাচাই করার জন্য আদর্শ। এই উদাহরণে দেখানো হয়েছে কিভাবে JWT টোকেন তৈরি, যাচাই এবং একটি protected endpoint ব্যবহার করা যায়, যা FastAPI এর মাধ্যমে শক্তিশালী এবং নিরাপদ ব্যবহারকারীর প্রমাণীকরণ প্রক্রিয়া নিশ্চিত করে।
FastAPI একটি নিরাপদ এবং দ্রুত API ডেভেলপমেন্ট ফ্রেমওয়ার্ক, যা নিরাপত্তা সংক্রান্ত বিভিন্ন ফিচার সরবরাহ করে। এর মধ্যে Password Hashing এবং Security Best Practices হল সিকিউর API এবং অ্যাপ্লিকেশন তৈরির জন্য অত্যন্ত গুরুত্বপূর্ণ।
এই পর্বে, আমরা FastAPI তে Password Hashing কিভাবে কার্যকরভাবে ব্যবহার করা যায় এবং Security Best Practices কী কী তা আলোচনা করব।
Password Hashing in FastAPI
Password Hashing হল পাসওয়ার্ড সুরক্ষিতভাবে সংরক্ষণ করার একটি গুরুত্বপূর্ণ প্রক্রিয়া। Hashing হল একটি একমুখী ফাংশন যা ইনপুট ডাটাকে নির্দিষ্ট দৈর্ঘ্যের স্ট্রিং (hash) এ রূপান্তরিত করে, যা পুনরায় মূল ইনপুট থেকে বের করা সম্ভব নয়। এটি পাসওয়ার্ড সংরক্ষণের নিরাপদ উপায়।
FastAPI তে password hashing করতে আপনি সাধারণত bcrypt বা passlib লাইব্রেরি ব্যবহার করতে পারেন। এখানে আমরা passlib ব্যবহার করব।
Step 1: Install passlib and bcrypt
প্রথমে passlib এবং bcrypt লাইব্রেরি ইনস্টল করুন:
pip install passlib[bcrypt]
Step 2: Password Hashing and Verification
এখন, আমরা Password Hashing এবং Verification কিভাবে করতে হয় তা দেখব।
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from passlib.context import CryptContext
# FastAPI অ্যাপ তৈরি করা
app = FastAPI()
# CryptContext ইনস্ট্যান্স তৈরি
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# Pydantic মডেল তৈরি
class User(BaseModel):
username: str
password: str
# Password Hashing ফাংশন
def hash_password(password: str) -> str:
return pwd_context.hash(password)
# Password Verify ফাংশন
def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
# রেজিস্টার বা পাসওয়ার্ড হ্যাশ করা
@app.post("/register/")
def register_user(user: User):
hashed_password = hash_password(user.password)
return {"username": user.username, "hashed_password": hashed_password}
# লগইন বা পাসওয়ার্ড ভেরিফাই করা
@app.post("/login/")
def login_user(user: User):
stored_hashed_password = "existing_hashed_password_from_db" # ডাটাবেস থেকে আসবে
if not verify_password(user.password, stored_hashed_password):
raise HTTPException(status_code=400, detail="Incorrect password")
return {"message": "Login successful"}
এখানে:
hash_password: পাসওয়ার্ডটি হ্যাশ করে দেয়।verify_password: পাসওয়ার্ডটি হ্যাশের সাথে মিলিয়ে দেখে।
এভাবে, পাসওয়ার্ড কখনো ডাটাবেসে প্লেইন টেক্সট হিসেবে সংরক্ষিত হবে না, বরং হ্যাশ করা থাকবে।
Step 3: Testing Password Hashing and Verification
রিকোয়েস্ট উদাহরণ (Register):
POST /register/
{
"username": "john_doe",
"password": "supersecretpassword"
}
রেসপন্স:
{
"username": "john_doe",
"hashed_password": "$2b$12$VxZfJ7ak0Yf6TG7Yl6UuBeXgtISohDq8fN76Y5.O3YFhFQhciHHKi" # Example hash
}
রিকোয়েস্ট উদাহরণ (Login):
POST /login/
{
"username": "john_doe",
"password": "supersecretpassword"
}
রেসপন্স:
{
"message": "Login successful"
}
এখানে, পাসওয়ার্ডটি হ্যাশ করা হয়েছে এবং যাচাই করার সময় পাসওয়ার্ডের হ্যাশটি ডাটাবেসে সংরক্ষিত থাকা একটি স্টোরড হ্যাশের সাথে মিলানো হয়েছে।
Security Best Practices in FastAPI
FastAPI তে সিকিউরিটি নিশ্চিত করার জন্য কিছু গুরুত্বপূর্ণ সেরা অনুশীলন বা Best Practices রয়েছে।
1. JWT Authentication (JSON Web Tokens)
FastAPI তে JWT ব্যবহার করে সুরক্ষিত অথেনটিকেশন করা যায়। JWT টোকেন দিয়ে আপনি ইউজারের সেশন ট্র্যাক করতে পারেন এবং API রিকোয়েস্টে অথেনটিকেশন নিশ্চিত করতে পারেন।
JWT Example:
pip install pyjwt
import jwt
from fastapi import FastAPI, Depends, HTTPException
from datetime import datetime, timedelta
from pydantic import BaseModel
app = FastAPI()
# Secret key
SECRET_KEY = "mysecretkey"
ALGORITHM = "HS256"
# Token Model
class Token(BaseModel):
access_token: str
token_type: str
# JWT Token Create
def create_access_token(data: dict, expires_delta: timedelta | None = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=15)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
@app.post("/token/", response_model=Token)
def login_for_access_token():
access_token_expires = timedelta(minutes=30)
access_token = create_access_token(data={"sub": "john_doe"}, expires_delta=access_token_expires)
return {"access_token": access_token, "token_type": "bearer"}
2. CORS (Cross-Origin Resource Sharing)
CORS (Cross-Origin Resource Sharing) কনফিগারেশন ব্যবহার করে আপনি নির্দিষ্ট ডোমেইন বা URL গুলোকে আপনার API অ্যাক্সেস দিতে পারেন। FastAPI-তে CORS কনফিগারেশন খুবই সহজ।
CORS Example:
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
origins = ["https://example.com", "https://www.example.com"]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # বা ["*"] সবার জন্য
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
3. Use HTTPS in Production
প্রোডাকশন পরিবেশে HTTP ব্যবহার না করে HTTPS ব্যবহার করা উচিত। HTTPS সার্ভার সেটআপ করা হলে সমস্ত ডাটা এনক্রিপ্টেড থাকবে, যা সিকিউর কমিউনিকেশন নিশ্চিত করে।
4. Rate Limiting
API-তে অতিরিক্ত রিকোয়েস্ট আটকাতে Rate Limiting ব্যবহার করা উচিত। FastAPI তে থার্ড-পার্টি লাইব্রেরি যেমন slowapi ব্যবহার করে আপনি রেট লিমিটিং অ্যাপ্লিকেশনে প্রয়োগ করতে পারেন।
pip install slowapi
5. Protect Sensitive Data (Environment Variables)
সেন্সিটিভ ডাটা (যেমন ডাটাবেস ক্রেডেনশিয়াল বা API কী) .env ফাইলে সংরক্ষণ করা উচিত। python-dotenv ব্যবহার করে আপনি এন্ডপয়েন্ট বা অন্যান্য কনফিগারেশন থেকে এগুলো লোড করতে পারেন।
pip install python-dotenv
FastAPI তে Password Hashing এবং Security Best Practices ব্যবহার করে আপনি একটি সুরক্ষিত এবং দ্রুত API তৈরি করতে পারেন। Password Hashing পাসওয়ার্ড সুরক্ষিতভাবে সংরক্ষণ এবং যাচাই করতে সাহায্য করে, আর JWT Authentication ব্যবহার করে সুরক্ষিত অথেনটিকেশন ব্যবস্থা তৈরি করা যায়। এছাড়া CORS, HTTPS, Rate Limiting, এবং Environment Variables এর মতো সিকিউরিটি সেরা অনুশীলনগুলি আপনার অ্যাপ্লিকেশনকে আরও নিরাপদ করে তোলে।
Role-Based Access Control (RBAC) একটি নিরাপত্তা নীতি যা ব্যবহারকারীদের বিভিন্ন ভূমিকা (Role) প্রদান করে এবং সেই ভূমিকার ভিত্তিতে তাদের অ্যাপ্লিকেশনের কিছু অংশে প্রবেশাধিকার (Access) নির্ধারণ করে। FastAPI-তে RBAC এবং Permission Management কার্যকরভাবে বাস্তবায়ন করা সম্ভব, যা API-এর নিরাপত্তা ব্যবস্থা উন্নত করে এবং বিভিন্ন ব্যবহারকারী এবং ভূমিকা অনুযায়ী অ্যাক্সেস নিয়ন্ত্রণ নিশ্চিত করে।
এখানে আমরা RBAC এবং Permission Management কিভাবে FastAPI তে বাস্তবায়ন করা যায় তা বিস্তারিতভাবে আলোচনা করব।
Step 1: FastAPI তে RBAC কনসেপ্ট
RBAC পদ্ধতিতে, ব্যবহারকারীদের একটি নির্দিষ্ট Role দেওয়া হয়, এবং সেই Role অনুযায়ী তারা অ্যাপ্লিকেশনের বিভিন্ন অংশে প্রবেশ করতে পারে। সাধারণত, কিছু প্রচলিত Role হতে পারে:
- Admin: পুরো অ্যাপ্লিকেশন অ্যাক্সেস আছে।
- User: নির্দিষ্ট কিছু অংশে অ্যাক্সেস।
- Guest: সীমিত অ্যাক্সেস।
উদাহরণ: Role-Based Access Control বাস্তবায়ন
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
app = FastAPI()
# OAuth2PasswordBearer ব্যবহার করা হচ্ছে টোকেন গ্রহণের জন্য
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Role model
class User(BaseModel):
username: str
role: str
# Dummy database (Users with roles)
fake_users_db = {
"admin_user": {"username": "admin_user", "role": "admin"},
"normal_user": {"username": "normal_user", "role": "user"},
}
# Role-based permission check
def check_role(role: str, token: str = Depends(oauth2_scheme)):
user = fake_users_db.get(token)
if user is None or user['role'] != role:
raise HTTPException(status_code=403, detail="Permission denied")
return user
# Endpoint accessible only by admin
@app.get("/admin/")
def get_admin_data(user: User = Depends(check_role)):
return {"message": f"Hello {user.username}, you have admin access!"}
# Endpoint accessible by any user (admin or normal)
@app.get("/user/")
def get_user_data(user: User = Depends(check_role)):
return {"message": f"Hello {user.username}, you have user access!"}
এখানে:
- check_role ফাংশনটি Role যাচাই করে, এবং Admin অথবা User হিসেবে অ্যাক্সেস প্রদান করে।
fake_users_dbএকটি ডামি ডাটাবেস যা ব্যবহারকারীর নাম এবং তাদের ভূমিকা ধারণ করে।
রিকোয়েস্ট উদাহরণ:
- GET
/admin/: শুধু admin_user অ্যাক্সেস পাবে। - GET
/user/: admin_user এবং normal_user উভয়েই অ্যাক্সেস পাবে।
Step 2: Permissions Management
Permission Management হচ্ছে আরও সূক্ষ্ম নিয়ন্ত্রণ যেখানে একটি নির্দিষ্ট রোলের মধ্যে একাধিক permissions থাকতে পারে। উদাহরণস্বরূপ:
- Admin রোলের জন্য সমস্ত অ্যাক্সেস (CRUD অপারেশন)।
- User রোলের জন্য শুধু
readঅ্যাক্সেস। - Guest রোলের জন্য শুধুমাত্র
read-onlyঅ্যাক্সেস।
উদাহরণ: Permission Management
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from typing import List
app = FastAPI()
# OAuth2PasswordBearer ব্যবহার করা হচ্ছে টোকেন গ্রহণের জন্য
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# User model
class User(BaseModel):
username: str
role: str
# Dummy database
fake_users_db = {
"admin_user": {"username": "admin_user", "role": "admin", "permissions": ["create", "read", "update", "delete"]},
"normal_user": {"username": "normal_user", "role": "user", "permissions": ["read"]},
"guest_user": {"username": "guest_user", "role": "guest", "permissions": ["read"]},
}
# Check permission function
def check_permission(permission: str, token: str = Depends(oauth2_scheme)):
user = fake_users_db.get(token)
if user is None or permission not in user['permissions']:
raise HTTPException(status_code=403, detail="Permission denied")
return user
# Endpoint where user needs 'read' permission
@app.get("/data/read/")
def read_data(user: User = Depends(check_permission)):
return {"message": f"Hello {user.username}, you have read access!"}
# Endpoint where user needs 'create' permission
@app.post("/data/create/")
def create_data(user: User = Depends(check_permission)):
return {"message": f"Hello {user.username}, you have create access!"}
এখানে:
- check_permission ফাংশনটি
permissionযাচাই করে, এবং read, create, update, delete অনুমতি ভিত্তিতে ব্যবহারকারীকে অ্যাক্সেস দেয়। - fake_users_db তে ব্যবহারকারীর permissions রয়েছে, যেমন "read", "create", "update", "delete"।
রিকোয়েস্ট উদাহরণ:
- GET
/data/read/: শুধুমাত্র admin_user, normal_user, এবং guest_user এর জন্য read permission প্রয়োজন। - POST
/data/create/: শুধুমাত্র admin_user এর জন্য create permission প্রয়োজন।
Step 3: JWT (JSON Web Token) ব্যবহার করে RBAC এবং Permission Management
JWT (JSON Web Token) ব্যবহার করে Authentication এবং Authorization ব্যবস্থা করা হয়। এটি একটি সাধারণ পদ্ধতি যেখানে ব্যবহারকারী প্রথমে লগইন করে একটি টোকেন পান এবং পরবর্তী রিকোয়েস্টে সেই টোকেনটি প্রেরণ করেন।
উদাহরণ: JWT ব্যবহার করে RBAC এবং Permission Management
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
import jwt
from datetime import datetime, timedelta
app = FastAPI()
# OAuth2PasswordBearer ব্যবহার করা হচ্ছে টোকেন গ্রহণের জন্য
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# User model
class User(BaseModel):
username: str
role: str
# JWT Secret key
SECRET_KEY = "mysecretkey"
# Dummy database (Users with roles)
fake_users_db = {
"admin_user": {"username": "admin_user", "role": "admin", "permissions": ["create", "read", "update", "delete"]},
"normal_user": {"username": "normal_user", "role": "user", "permissions": ["read"]},
}
# JWT Token Generation
def create_access_token(username: str, role: str):
expiration = datetime.utcnow() + timedelta(hours=1)
payload = {"sub": username, "role": role, "exp": expiration}
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
# Token Validation
def decode_token(token: str):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token has expired")
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
# Permission Check function using decoded JWT
def check_permission(permission: str, token: str = Depends(oauth2_scheme)):
decoded_token = decode_token(token)
user = fake_users_db.get(decoded_token["sub"])
if user is None or permission not in user['permissions']:
raise HTTPException(status_code=403, detail="Permission denied")
return user
# Endpoint with RBAC and Permissions
@app.get("/data/read/")
def read_data(user: User = Depends(check_permission)):
return {"message": f"Hello {user.username}, you have read access!"}
@app.post("/data/create/")
def create_data(user: User = Depends(check_permission)):
return {"message": f"Hello {user.username}, you have create access!"}
এখানে:
- JWT Token তৈরি করার জন্য
create_access_tokenফাংশন ব্যবহার করা হয়েছে। - Token যাচাই করা হচ্ছে
decode_tokenফাংশনের মাধ্যমে এবং কাস্টম permission check করা হচ্ছে।
রিকোয়েস্ট উদাহরণ:
- POST
/tokenরিকোয়েস্টের মাধ্যমে JWT টোকেন পেতে হবে, পরে সেই টোকেন সহ GET/data/read/বা POST/data/create/রিকোয়েস্ট পাঠানো হবে।
FastAPI-তে Role-Based Access Control (RBAC) এবং Permission Management বাস্তবায়ন করা অত্যন্ত সহজ এবং শক্তিশালী। আপনি OAuth2, JWT, এবং Permission Check ফাংশন ব্যবহার করে API-এর নিরাপত্তা ব্যবস্থা উন্নত করতে পারেন। RBAC এবং Permission Management কৌশলগুলি API-এর বিভিন্ন ব্যবহারকারীর ভূমিকা এবং তাদের অ্যাক্সেস কনট্রোল নিশ্চিত করতে সাহায্য করে, যা একটি সুরক্ষিত এবং কার্যকর API তৈরি করার জন্য অপরিহার্য।
Read more